package cn.shadow.message;

import cn.shadow.bean.PlayerModule;
import cn.shadow.concurrent.DisruptorExecutor;
import cn.shadow.entity.ConnectedUser;
import cn.shadow.module.login.LoginModuleMessages;
import cn.shadow.service.Services;
import cn.shadow.service.UserService;
import cn.shadow.service.WorldService;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;


import static cn.shadow.message.DisconnectReason.EXPECT_LOGIN_BUT_RECEIVE_OTHER;
import static cn.shadow.utils.BufferUtil.readVarInt32;

@Slf4j
@Data
public class MessageWorker implements Worker {
    private Services services;
    private static final long MAX_TIME_OUT = 20;
    /**
     * 信息传输通道
     */
    private ChannelSender channelSender;
    private long lastPingTime;

    private volatile ConnectedUser connectedUser;

    private DisruptorExecutor taskExc;

    public MessageWorker(Channel channel, Services services) {
        this.services = services;
        this.channelSender = new ChannelSender(channel, services.getModuleHub());
        lastPingTime = System.currentTimeMillis();
    }

    public boolean checkTimeout(long ctime) {
        if (ctime - lastPingTime > MAX_TIME_OUT) {
            disconnect(DisconnectReason.REASON_UNKNOWN);
            return true;
        }
        return false;
    }

    private void disconnect(DisconnectReason reasonUnknown) {

    }

    @Override
    public void onConnected() {

    }

    @Override
    public void onDisconnected() {
        WorldService worldService =services.getWorldService();
        if (connectedUser != null)
            worldService.removeUser(connectedUser);
        this.connectedUser = null;
    }

    @Override
    public void onMessage(ByteBuf buffer) {
        ByteBuf copy = buffer.copy();
        int checkSumByte = copy.readUnsignedByte();
        log.info("checkSumByte=" + checkSumByte);
        short offset = copy.readUnsignedByte();// 跳过offset
        log.info("offset = " + offset);
        int moduleID = readVarInt32(copy); //模块id
        int sequenceID = readVarInt32(copy); //顺序id
        //先判断有没有登录
        final ConnectedUser connectedUser = this.connectedUser;
        if (connectedUser == null) { //未登录
            doLogin(moduleID, sequenceID, copy);
            return;
        }

        PlayerModule playerModule = connectedUser.getPlayerModule();
        if (playerModule != null && moduleID != LoginModuleMessages.MODULE_ID) {
            //已经创建了角色
            taskExc.processMessage(copy, moduleID, sequenceID, playerModule); //用户线程自己处理自己的事情
            return;
        }
        //创建角色
        UserService userService = services.getDbService().getUserService();
        userService.processCreatePlayer(copy, sequenceID, this);
    }

    /**
     * 没有登录就进行登录
     */
    private void doLogin(int moduleID, int sequenceID, ByteBuf buffer) {
        if (moduleID != LoginModuleMessages.MODULE_ID) { //未登录就发送其他消息
            log.warn("未登录, 但是收到的消息不是登录模块的!{}-{}", moduleID, sequenceID);
            disconnect(EXPECT_LOGIN_BUT_RECEIVE_OTHER);
            return;
        }
        UserService userService = services.getDbService().getUserService();
        switch (sequenceID) {
            case LoginModuleMessages.C2S_CREATE_OR_LOGIN_BY_NAME:
                userService.processCreateOrLoginByName(buffer, this);
                return;
            case LoginModuleMessages.C2S_WEB_LOGIN:
                processWebLogin(buffer);
            default:
                log.warn("processNotLoggedInMessage收到未知消息: {}", sequenceID);
        }
    }

    /**
     * 网页登录
     */
    private void processWebLogin(ByteBuf buffer) {
    }


}
